<template>
  <el-card>
    <div slot="header">轮播图</div>
    <div class="slider-box">
      <div id="slider" class="slider">
        <ul ref="slider-ul" class="gl-flex-row">
          <li>
            <img
              width="520"
              height="280"
              :src="imgSrc[imgSrc.length - 1]"
              alt=""
            />
          </li>
          <li v-for="(item, index) in imgSrc">
            <img width="520" height="280" :src="item" alt="" />
          </li>
          <li>
            <img width="520" height="280" :src="imgSrc[0]" alt="" />
          </li>
        </ul>
        <!-- 向左按钮 -->
        <div class="arrow-box left-box" @click="nextLeft">
          <span>&lt;</span>
        </div>
        <!-- 向右按钮 -->
        <div class="arrow-box right-box" @click="nextRight">
          <span>&gt;</span>
        </div>
        <!-- 小圆点 -->
        <div class="index-box">
          <ol>
            <li
              v-for="i in imgSrc.length"
              :class="{ active: activeIndex === i }"
              @click="changeSlider(i)"
            ></li>
          </ol>
        </div>
      </div>
    </div>
  </el-card>
</template>

<script>
export default {
  data() {
    return {
      // 轮播图中图片的宽度
      sliderPicWidth: 520,
      imgSrc: [
        'https://img.alicdn.com/imgextra/i1/6000000006732/O1CN01OIsx9S1zbJ0TwkB94_!!6000000006732-0-octopus.jpg',
        'https://img.alicdn.com/imgextra/i2/6000000004443/O1CN01LU3qnv1igwPbvzfKz_!!6000000004443-0-octopus.jpg',
        'https://aecpm.alicdn.com/simba/img/TB1XotJXQfb_uJkSnhJSuvdDVXa.jpg',
        'https://aecpm.alicdn.com/simba/img/TB1JNHwKFXXXXafXVXXSutbFXXX.jpg',
        'https://aecpm.alicdn.com/imgextra/i3/890482188/O1CN01eTjZP11S29Hg082mf_!!890482188-0-alimamazszw.jpg'
      ],
      // 当前slider的索引
      activeIndex: 1,
      // 是否处在动画中
      animated: false
    }
  },
  mounted() {
    this.$refs['slider-ul'].style.left = '-520px'
  },
  methods: {
    /**
     * @description:
     * @param {*} offset
     * @return {*}
     */
    animate(offset) {
      // 防止抖动
      this.animated = true
      // 运动时间（单位s）
      const time = 200
      // 频率, 每16.7ms变化一次（频率要60帧/s）
      const rate = 16.7
      // 速度，每次移动的距离
      let speed = offset / (time / rate)

      let ulLeft = parseFloat(this.$refs['slider-ul'].style.left)
      // 目标位置
      let goal = ulLeft - offset
      // 间隔动画效果
      let animate = setInterval(() => {
        // 获取最新的边距
        let ulLeft = parseFloat(this.$refs['slider-ul'].style.left)

        if (
          ulLeft == goal ||
          Math.abs(Math.abs(ulLeft) - Math.abs(goal)) < Math.abs(speed)
        ) {
          ulLeft = goal
          this.$refs['slider-ul'].style.left = goal + 'px'
          clearInterval(animate)
          this.animated = false

          if (ulLeft == 0) {
            // 到达最左边的图片
            this.$refs['slider-ul'].style.left =
              -this.imgSrc.length * this.sliderPicWidth + 'px'
          } else if (
            // 到达最右边的图片
            ulLeft ==
            -(this.imgSrc.length + 1) * this.sliderPicWidth
          ) {
            this.$refs['slider-ul'].style.left = -this.sliderPicWidth + 'px'
          }
        } else {
          // 没有到达目标距离
          this.$refs['slider-ul'].style.left = ulLeft - speed + 'px'
        }
      }, rate)
    },
    /**
     * @description:
     * @param {*} offset
     * @return {*}
     */
    move(offset) {
      this.animate(offset)
    },
    /**
     * @description: 轮播图向左移
     * @param {*}
     * @return {*}
     */
    nextLeft() {
      if (this.animated) {
        return
      }
      this.activeIndex--
      if (this.activeIndex == 0) {
        this.activeIndex = this.imgSrc.length
      }
      this.move(-this.sliderPicWidth)
    },
    /**
     * @description: 轮播图向右移
     * @param {*}
     * @return {*}
     */
    nextRight() {
      if (this.animated) {
        return
      }
      this.activeIndex++
      if (this.activeIndex > this.imgSrc.length) {
        this.activeIndex = 1
      }
      this.move(this.sliderPicWidth)
    },
    /**
     * @description: 点击小圆点，切换图片
     * @param {*} index
     * @return {*}
     */
    changeSlider(index) {
      let offset = (index - this.activeIndex) * this.sliderPicWidth

      this.activeIndex = index
      this.move(offset)
    }
  }
}
</script>

<style lang="less" scoped>
.slider-box {
  .slider {
    width: 520px;
    height: 280px;
    position: relative;
    overflow: hidden;

    ul {
      position: absolute;
      top: 0px;
      // left: -520px;
      padding: 0;
      margin: 0;
      li {
        list-style: none;
      }
    }

    .arrow-box {
      background-color: rgba(0, 0, 0, 0.2);
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      width: 50px;
      height: 50px;
      color: #fff;
      line-height: 50px;
      text-align: center;
      font-size: 20px;
      cursor: pointer;
    }

    .left-box {
      left: 0px;
    }

    .right-box {
      right: 0px;
    }

    .index-box {
      position: absolute;
      bottom: 3%;
      left: 10%;

      ol {
        height: 14px;
        display: flex;
        justify-content: space-evenly;
        align-items: center;
        background-clip: rgba(0, 0, 0, 0.6);

        li {
          width: 10px;
          height: 10px;
          border-radius: 50%;
          background: #fff;
          list-style: none;
          cursor: pointer;
          margin-right: 5px;

          &.active {
            background-color: #e1251b;
          }
        }
      }
    }
  }
}
</style>
